ToBeanRowTransformer.java
package org.codefilarete.stalactite.mapping;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import org.codefilarete.stalactite.sql.result.ColumnedRow;
import org.codefilarete.tool.Reflections;
import org.codefilarete.tool.bean.FieldIterator;
import org.codefilarete.tool.collection.Iterables;
import org.codefilarete.reflection.Accessors;
import org.codefilarete.reflection.Mutator;
import org.codefilarete.stalactite.sql.ddl.structure.Column;
import org.codefilarete.stalactite.sql.ddl.structure.Table;
/**
* Class for transforming columns into a bean.
*
* @author Guillaume Mary
*/
public class ToBeanRowTransformer<C> extends AbstractTransformer<C> {
private final Map<Column<?, ?>, Mutator<C, Object>> columnToMember;
/**
* A constructor that maps all fields of a class by name
*
* @param clazz instance type to be built
* @param table the mapped table
* @param warnOnMissingColumn indicates if an Exception must be thrown when no {@link Column} in the {@link Table} can be found for a field
* (matching name)
*/
public ToBeanRowTransformer(Class<C> clazz, Table table, boolean warnOnMissingColumn) {
this(clazz, new HashMap<>(10));
Map<String, Column> columnPerName = table.mapColumnsOnName();
FieldIterator fieldIterator = new FieldIterator(clazz);
Iterables.stream(fieldIterator).forEach(field -> {
Column column = columnPerName.get(field.getName());
if (column == null) {
if (warnOnMissingColumn) {
throw new UnsupportedOperationException("Missing column for field " + Reflections.toString(field));
}
} else {
columnToMember.put(column, Accessors.mutatorByField(field));
}
}
);
}
/**
*
* @param clazz the constructor to be used to instantiate a new bean
* @param columnToMember the mapping between key in rows and helper that fixes values of the bean
*/
public ToBeanRowTransformer(Class<C> clazz, Map<? extends Column<?, ?>, ? extends Mutator<C, Object>> columnToMember) {
super(clazz);
this.columnToMember = (Map<Column<?, ?>, Mutator<C, Object>>) columnToMember;
}
/**
*
* @param beanFactory factory to be used to instantiate a new bean
* @param columnToMember the mapping between key in rows and helper that fixes values of the bean
*/
public ToBeanRowTransformer(Function<? extends ColumnedRow, C> beanFactory,
Map<? extends Column<?, ?>, ? extends Mutator<C, Object>> columnToMember) {
super(beanFactory);
this.columnToMember = (Map<Column<?, ?>, Mutator<C, Object>>) columnToMember;
}
protected ToBeanRowTransformer(Function<ColumnedRow, C> beanFactory,
Map<? extends Column<?, ?>, ? extends Mutator<C, Object>> columnToMember,
Collection<TransformerListener<C>> rowTransformerListeners) {
super(beanFactory, rowTransformerListeners);
this.columnToMember = (Map<Column<?, ?>, Mutator<C, Object>>) columnToMember;
}
public Map<Column<?, ?>, Mutator<C, Object>> getColumnToMember() {
return columnToMember;
}
@Override
public void applyRowToBean(ColumnedRow source, C targetRowBean) {
for (Entry<Column<?, ?>, Mutator<C, Object>> columnFieldEntry : columnToMember.entrySet()) {
Object propertyValue = source.get(columnFieldEntry.getKey());
applyValueToBean(targetRowBean, columnFieldEntry, propertyValue);
}
}
protected void applyValueToBean(C targetRowBean, Entry<? extends Column, ? extends Mutator<C, Object>> columnFieldEntry, Object propertyValue) {
columnFieldEntry.getValue().set(targetRowBean, propertyValue);
}
}